

(() => {
  /* 
    ● null 和 undefined
      ○ null: 表示一个空值, 它只有一个值null
      ○ undefined: 表示一个未定义的值, 它只有一个值undefined
      ○ 在非严格模式下:  null 和 undefined 是所有类型的子类型。 可以赋值给任意其它类型的变量
      ○ 在严格模式下: null和undefined不可以赋值给别的类型(any除外)
  */

  // let n: null = null
  // let u: undefined = undefined
  // let a: number = 2
  // a = n  // error
  // a = u // error

  /* 
  any: 任何类型，该类型会跳过类型检查，不太推荐使用。可以做任何操作
  */
  // let a: any
  // a = 5
  // a = 'hello'
  // let n: number = a
  // a.test()

  /* 
  ● unknown: 未知的类型, 与any类型类似, 但也有区别
  ○ 相同点: 都可以被赋值为任意类型值
  ○ 不同点: 
    ■ any类型可以赋值给其它任意类型, 而unknown类型不能赋值给非any的其它类型
    ■ any类型可以直接读取任意属性和调用任意方法, 但unknown类型不能直接使用, 需要先进行类型断言后才能使用
  */
  let a: string
  let b: unknown
  b = 5
  b = 'abc'
  // a = b 
  // b.test()  // error

  /* 
  never: 指示一个从不出现的类型。它表示永远不会有值的类型。常常用于函数永远不会正常结束的返回类型。
  */
  function fn(): never {
    throw new Error('xxxx')
  }

  /* 
  void: 没有任何类型, 经常用来定义函数没有返回值。
  */
  function logMessage(message: string): void {
    console.log(message);
    // 不写return
    return undefined
  
    // return null  // 在非严格模式可以, 但在严格模式下 error
    // return '其它任意类型值都不可以'   // error
  }

})()
